/*
 * GameUtils.cpp
 *
 *  Created on: May 19, 2012
 *      Author: gonzalo
 */

#include "GameUtils.h"
#include "math.h"
#include "../lib/SDL_rotozoom.h"
#include "SDL/SDL_image.h"
#include "SurfaceUtils.h"

#include "../Constantes.h"

#define MAX_OVERLAPING_RETRIES 40

//TODO implementar esto, tiene q pasar a otra instancia.
void GameUtils::resolveOverlaping(const std::list<DTOAsteroide*>& asteroides,DTOShipStatus* dtoShipStatus,int widht,int height){
	//Check if its overlaping with other
	bool overlaps = true;
	int retries = 0;

	std::list<DTOAsteroide*> asteroidesCopy;

	//Start the seed
	srand(time(0));

	DTOAsteroide* asteEvaluating = NULL;
	while(overlaps && retries < MAX_OVERLAPING_RETRIES ){
		overlaps = false;
		//Copy the list
		asteroidesCopy = asteroides;
		while(!asteroidesCopy.empty()){
			asteEvaluating = *(asteroidesCopy.begin());

			if (isOverlapping(asteEvaluating,dtoShipStatus)){
				dtoShipStatus->posX = getRandValueInRange(widht);
				dtoShipStatus->posY = getRandValueInRange(height);


				overlaps = true;

				retries++;

				std::stringstream stream2;
				stream2 << "NUEVO VALOR TRAS colision !: ";
				stream2 << " X" << dtoShipStatus->posX;
				stream2 << " Y" << dtoShipStatus->posY;
				stream2 << " Retry :" << retries;
				Logger::log("Persistidor","isColision", &stream2);


				//Cut the while
				break;
			}

			std::stringstream stream2;
			asteroidesCopy.pop_front();
		}

	}

}

int GameUtils::getRandValueInRange(int dimension){
	return (rand() % dimension);
}

bool GameUtils::isOverlapping(DTOAsteroide* asteroide,DTOShipStatus* dtoShipStatus){

	if(dtoShipStatus == NULL)
		return false;

	SDL_Surface* shipSurfaceAux = SurfaceUtils::loadImage(dtoShipStatus->imagen);
	SDL_Surface* shipSurface= rotozoomSurface(shipSurfaceAux , dtoShipStatus->angle, 1.,SMOOTHING_OFF);
	SDL_FreeSurface(shipSurfaceAux);

	if(shipSurface == NULL)	return false;
	shipSurface->clip_rect.x = dtoShipStatus->posX - shipSurface->clip_rect.w/2;
	shipSurface->clip_rect.y = dtoShipStatus->posY - shipSurface->clip_rect.h/2 ;

	SDL_Surface* asteroideSurfaceAux = SurfaceUtils::loadImage(asteroide->tipo->imagePath);
	SDL_Surface* asteroideSurface= rotozoomSurface(asteroideSurfaceAux , dtoShipStatus->angle, 1.,SMOOTHING_OFF);
	asteroideSurface = SurfaceUtils::resizeSurface(asteroide->tipo->ancho,asteroide->tipo->ancho,asteroideSurface);
	SDL_FreeSurface(asteroideSurfaceAux);
	if(asteroideSurface == NULL)return false;
	asteroideSurface->clip_rect.x = asteroide->x - asteroideSurface->clip_rect.w/2;
	asteroideSurface->clip_rect.y = asteroide->y - asteroideSurface->clip_rect.h/2 ;

	bool overlap = GameUtils::overlaps(*shipSurface,*asteroideSurface);

	SDL_FreeSurface(asteroideSurface);
	SDL_FreeSurface(shipSurface);

	return overlap;

}



bool GameUtils::overlaps(SDL_Surface surface1,SDL_Surface surface2){

	bool isSurface1Origen =false;


	if(surface1.clip_rect.x < 0) surface1.clip_rect.x =0;
	if(surface1.clip_rect.y < 0) surface1.clip_rect.y =0;
	if(surface2.clip_rect.x < 0) surface2.clip_rect.x =0;
	if(surface2.clip_rect.y < 0) surface2.clip_rect.y =0;


	int xOrigin = 0;
	int yOrigin = 0;
	//Traslado ambos rectangulos
	//Tomo como cero al que esta mas cerca del origen.

	//Calculo el modulo, para evitar valores negativos
	float mod1 = sqrt(pow(surface1.clip_rect.x,2) + pow(surface1.clip_rect.y,2));
	float mod2 = sqrt(pow(surface2.clip_rect.x,2) + pow(surface2.clip_rect.y,2));

	if(mod2 > mod1  || mod1 == mod2){
		xOrigin = surface1.clip_rect.x;
		yOrigin = surface1.clip_rect.y;
		isSurface1Origen =true;
	}else{
		xOrigin = surface2.clip_rect.x;
		yOrigin = surface2.clip_rect.y;
		isSurface1Origen =false;
	}

	//Muevo ambas superficies al origine
	surface1.clip_rect.x -= xOrigin;
	surface1.clip_rect.y -= yOrigin;

	surface2.clip_rect.x -= xOrigin;
	surface2.clip_rect.y -= yOrigin;


	if(surface1.clip_rect.x < 0) surface1.clip_rect.x =0;
	if(surface1.clip_rect.y < 0) surface1.clip_rect.y =0;
	if(surface2.clip_rect.x < 0) surface2.clip_rect.x =0;
	if(surface2.clip_rect.y < 0) surface2.clip_rect.y =0;


	//Calculo el modulo


	float pos1;
	float pos2;
	if(isSurface1Origen){
		pos1= sqrt(pow(surface1.clip_rect.h,2) + pow(surface1.clip_rect.w,2));
		pos2= sqrt(pow(surface2.clip_rect.x,2) + pow(surface2.clip_rect.y,2));


		if(pos1 > pos2){
			//Hay contacto
			return true;
		}

	}else{
		pos1= sqrt(pow(surface1.clip_rect.x,2) + pow(surface1.clip_rect.y,2));
		pos2= sqrt(pow(surface2.clip_rect.h,2) + pow(surface2.clip_rect.w,2));

		if(pos2 > pos1){
			//Hay contacto
			return true;
		}
	}

	return false;
}



